home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_01 / 9n01114a < prev    next >
Text File  |  1990-11-27  |  37KB  |  1,472 lines

  1. /*0*********************************************************
  2. *   Richard Carver                            July 1990
  3. *   This program demonstrates interprocess communication
  4. *   between several tasks using the iRMX II Operating
  5. *   System.
  6. *
  7. *   Two tasks are used for resource control.  The
  8. *   clock_task() controls use of the hardware clock and the
  9. *   crt_task() controls use of the display screen.
  10. *
  11. *   The count_task() competes with the clock_task() for
  12. *   use of the crt_task() services.  The timer_task() uses
  13. *   the services of the clock_task() for a software timer.
  14. *
  15. *   The initial task, main(), starts every thing up and,
  16. *   when the timer_task() finishes, shuts everything down.
  17. ***********************************************************/
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <rmxc.h>         /* iRMX OS calls & structures   */
  23. #include <rmxerr.h>       /* iRMX status codes (defines)  */
  24. #include <delay.h>        /* Hardcoded delay loop macros  */
  25.  
  26. #define ERROR   (0xFFFF)    /* Error Condition  */
  27.  
  28. #define FALSE   (0)
  29. #define TRUE    (!FALSE)
  30.  
  31. #define MAX_CLOCK_RETRIES   (4)
  32.  
  33. /* The NULL token (similar to NULL pointer) */
  34.  
  35. #define NUL_TKN   ((selector)0)
  36.  
  37. /* Options for rqgettasktokens()  */
  38.  
  39. #define THIS_TASK (0x00)
  40. #define THIS_JOB  (0x01)
  41. #define PARAM_OBJ (0x02)
  42. #define ROOT_JOB  (0x03)
  43.  
  44. /* Options for rqcreatemailbox()  */
  45.  
  46. #define FIFO_OBJ_MBX      (0x0000)
  47. #define PRIORITY_OBJ_MBX  (0x0001)
  48. #define FIFO_DATA_MBX     (0x0020)
  49. #define PRIORITY_DATA_MBX (0x0021)
  50.  
  51. /* Options for rqcreatesemaphore()  */
  52.  
  53. #define FIFO_SEM      (0x0000)
  54. #define PRIORITY_SEM  (0x0001)
  55.  
  56. #define SEM_INIT_0    (0)
  57. #define SEM_MAX_1     (1)
  58.  
  59. /* Common wait times for iRMX System Calls  */
  60.  
  61. #define NO_WAIT       (0x0000)
  62. #define WAIT_FOREVER  (0xFFFF)
  63.  
  64. /* Options for rqcreatetask() */
  65.  
  66. #define NO_FLOAT    (0x0000)
  67. #define DEFAULT_STACK_SIZE    ((unsigned int)2048)
  68.  
  69. /* Task Priorities  */
  70.  
  71. #define CLOCK_TASK_PRIORITY   ((unsigned char)48)
  72. #define TIMER_TASK_PRIORITY       ((unsigned char)150)
  73. #define CRT_TASK_PRIORITY     ((unsigned char)200)
  74. #define COUNT_TASK_PRIORITY   ((unsigned char)200)
  75.  
  76. /* Defines For Hardware Clock */
  77. /* Clock Interrupt Level */
  78.  
  79. #define CLOCK_INT_LEVEL (0x26)
  80.  
  81. /* Clock Ports */
  82.  
  83. #define ADR_PORT  ((unsigned short)0xA060)
  84. #define DAT_PORT  ((unsigned short)0xA062)
  85. #define CNT_PORT  ((unsigned short)0xA064)
  86. #define PIO_PORT  ((unsigned short)0xA066)
  87.  
  88. /* Clock Port I/O Operations */
  89.  
  90. #define PIO_READ  ((unsigned char)0x82)
  91. #define PIO_WRITE ((unsigned char)0x80)
  92.  
  93. /* Clock Registers */
  94.  
  95. #define SEC01_REG (0x00)
  96. #define SEC10_REG (0x01)
  97. #define MIN01_REG (0x02)
  98. #define MIN10_REG (0x03)
  99. #define HRS01_REG (0x04)
  100. #define HRS10_REG (0x05)
  101. #define DAT01_REG (0x07)
  102. #define DAT10_REG (0x08)
  103. #define MON01_REG (0x09)
  104. #define MON10_REG (0x0A)
  105. #define YRS01_REG (0x0B)
  106. #define YRS10_REG (0x0C)
  107.  
  108. /* Clock Control Lines */
  109.  
  110. #define CNT_RST     ((unsigned char)0x00)
  111. #define INT_ENB     ((unsigned char)0x20)
  112. #define HOLD_HIGH   ((unsigned char)0x10)
  113. #define HOLD_READ   ((unsigned char)0x30)
  114. #define HOLD_WRITE  ((unsigned char)0x50)
  115.  
  116. /* Defines for months */
  117.  
  118. #define JANUARY     (1)
  119. #define FEBRUARY    (2)
  120. #define MARCH       (3)
  121. #define DECEMBER    (12)
  122.  
  123. /* Time/Date and Timers Data Structure  */
  124.  
  125. #define MAX_TIMERS    (10)
  126.  
  127. struct SYS_TIME_STR
  128.   {
  129.   unsigned char change_flg;
  130.   unsigned char second;
  131.   unsigned char minute;
  132.   unsigned char hour;
  133.   unsigned char date;
  134.   unsigned char month;
  135.   unsigned char year;
  136.  
  137.   struct TIMER_STR
  138.     {
  139.     unsigned char in_use;
  140.     unsigned int  count;
  141.     unsigned int  timeout;
  142.     selector    sem_tkn;
  143.     }timer[MAX_TIMERS];
  144.   };
  145.  
  146. /* Request Message format for the Display Task  */
  147.  
  148. struct CRT_REQ_STR
  149.   {
  150.   unsigned char *msg_ptr;
  151.   unsigned int  row;
  152.   unsigned int  col;
  153.   };
  154.  
  155. /* Object Catalog Names */
  156.  
  157. const unsigned char
  158.   clock_sem_name[] = "\011CLOCK_SEM",
  159.   init_sem_name[] = "\010INIT_SEM";
  160.  
  161. const unsigned char
  162.   time_seg_name[] = "\010TIME_SEG";
  163.  
  164. const unsigned char
  165.   crt_req_mbx_name[] = "\007CRT_MBX";
  166.  
  167. const unsigned char
  168.   crt_shtdwn_sem_name[] = "\012CRT_SHTDWN",
  169.   clock_shtdwn_sem_name[] = "\014CLOCK_SHTDWN",
  170.   count_shtdwn_sem_name[] = "\014COUNT_SHTDWN";
  171.  
  172. /* Days Per Month */
  173.  
  174. const unsigned char
  175.   days_in_month[12] =
  176.   {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  177.  
  178. /* Global System Time/Date Structure */
  179.  
  180. selector  sys_time_seg;
  181. struct SYS_TIME_STR *sys_time;
  182.  
  183. /* Task declarations  */
  184.  
  185. void clock_task(void);
  186. void crt_task(void);
  187. void timer_task(void);
  188. void count_task(void);
  189.  
  190. /* Task objects (global for debugging purposes) */
  191.  
  192. selector    clock_tsk;
  193. selector    crt_tsk;
  194. selector    timer_tsk;
  195. selector    count_tsk;
  196.  
  197. /*1*********************************************************
  198. * Task:     main()  (the initial task)
  199. *
  200. * Summary:  Starts it all up and shuts it all down.
  201. *
  202. * Caveats:  None
  203. ***********************************************************/
  204.  
  205. void main(void)
  206.   {
  207.   selector  current_job;      /* current job            */
  208.   selector  init_sem;         /* initilaization sem     */
  209.   selector  clock_sem;        /* time/date shared memory*/
  210.   selector  clock_shtdwn_sem; /* clock_task() shutdown  */
  211.   selector  count_shtdwn_sem; /* count_task() shutdown  */
  212.   selector  crt_shtdwn_sem;   /* crt_task() shutdown    */
  213.   selector  sys_time_seg;     /* time/date data segment */
  214.  
  215.   unsigned int    status;     /* iRMX condition code    */
  216.  
  217.   struct EXCEPTIONSTRUCT  exceptioninfo;
  218.  
  219.  
  220. /*  Disable current task's exception handler  */
  221.  
  222.   rqgetexceptionhandler(&exceptioninfo, &status);
  223.   exceptioninfo.exceptionmode = 0;
  224.   rqsetexceptionhandler(&exceptioninfo, &status);
  225.  
  226. /*  Get Token For Current Job */
  227.  
  228.   current_job = rqgettasktokens(THIS_JOB, &status);
  229.  
  230. /*  Create and catalog the semaphore used for */
  231. /*  accessing the shared clock data.          */
  232.  
  233.   clock_sem = rqcreatesemaphore(SEM_INIT_0,
  234.     SEM_MAX_1, PRIORITY_SEM, &status);
  235.   rqcatalogobject(current_job,
  236.     clock_sem, &clock_sem_name, &status);
  237.  
  238. /*  Create and catalog the semaphore used for */
  239. /*  synchronizing tasks during initialization */
  240. /*  and shutdown.                             */
  241.  
  242.   init_sem = rqcreatesemaphore(SEM_INIT_0,
  243.     99, FIFO_SEM, &status);
  244.   rqcatalogobject(current_job,
  245.     init_sem, &init_sem_name, &status);
  246.  
  247. /*  Create and catalog the segment of memory  */
  248. /*  used to hold the shared time/date data.   */
  249.  
  250.   sys_time_seg = rqcreatesegment(
  251.     sizeof(struct SYS_TIME_STR), &status);
  252.   rqcatalogobject(current_job,
  253.     sys_time_seg, &time_seg_name, &status);
  254.  
  255. /*  Create and catalog the semaphores used to */
  256. /*  signal task shutdown.                     */
  257.  
  258.   clock_shtdwn_sem = rqcreatesemaphore(SEM_INIT_0,
  259.     SEM_MAX_1, FIFO_SEM, &status);
  260.   rqcatalogobject(current_job,
  261.     clock_shtdwn_sem, &clock_shtdwn_sem_name, &status);
  262.  
  263.   crt_shtdwn_sem = rqcreatesemaphore(SEM_INIT_0,
  264.     SEM_MAX_1, FIFO_SEM, &status);
  265.   rqcatalogobject(current_job,
  266.     crt_shtdwn_sem, &crt_shtdwn_sem_name, &status);
  267.  
  268.   count_shtdwn_sem = rqcreatesemaphore(SEM_INIT_0,
  269.     SEM_MAX_1, FIFO_SEM, &status);
  270.   rqcatalogobject(current_job,
  271.     count_shtdwn_sem, &count_shtdwn_sem_name, &status);
  272.  
  273. /*  Create the crt_task().  Wait for the task to  */
  274. /*  indicate it has completed initialization.     */
  275.  
  276.   crt_tsk = rqcreatetask(CRT_TASK_PRIORITY, &crt_task,
  277.     NUL_TKN, NULL, DEFAULT_STACK_SIZE, NO_FLOAT, &status);
  278.  
  279.   rqreceiveunits(init_sem, 1, WAIT_FOREVER, &status);
  280.  
  281. /*  Create the clock_task().  Wait for the task   */
  282. /*  to indicate it has completed initialization.  */
  283.  
  284.   clock_tsk = rqcreatetask(CLOCK_TASK_PRIORITY, &clock_task,
  285.     NUL_TKN, NULL, DEFAULT_STACK_SIZE, NO_FLOAT, &status);
  286.  
  287.   rqreceiveunits(init_sem, 1, WAIT_FOREVER, &status);
  288.  
  289. /*  Create the count_task().  Wait for the task   */
  290. /*  to indicate it has completed initialization.  */
  291.  
  292.   count_tsk = rqcreatetask(COUNT_TASK_PRIORITY, &count_task,
  293.     NUL_TKN, NULL, DEFAULT_STACK_S